import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import org.jgap.gp.IGPProgram;
import org.jgap.gp.terminal.Variable;

//main class, in case of train trains svm&GP, otherwise predicts using both models
public class mainClass {

	public static ArrayList<Stock> stocks=new ArrayList<Stock>();
	public static ArrayList<Double> preds=new ArrayList<Double>();
	public static String numDays,datafolder,filenames,modelFile;
	public static ArrayList<String> GPchosen=new ArrayList<String>(), SVMchosen=new ArrayList<String>();

	//main method
	public static void main(String[] args) throws IOException {
	
	
		boolean isTrain=false;
		
		if(args[0].intern()=="-t")
			isTrain=true;
		
		//getting arguments
		numDays=args[1];
		modelFile=args[4];
		filenames=args[3];
		datafolder=args[2];
		
		getStocks();
		
		//train
		if(isTrain)
		{
			//train GP
			trainGP();
			stocks=new ArrayList<Stock>();
			getStocks();
			
			String[] arr=new String[5];
			arr[0]="train.txt";
			arr[1]="modsvm.model";
			arr[2]=datafolder;
			arr[3]=filenames;
			arr[4]=numDays;
			//train SVM
			//svm_train.main_train(arr,stocks);
			SVMtrain.main_train(arr, stocks);
		}
		//predict
		else
		{
			//predict GP
			predictGP();
			stocks=new ArrayList<Stock>();
			getStocks();
			String buyFile=args[5];
			
			//predict SVM
			SVMpredict.main_predict(new String[]{"modsvm.model",buyFile,datafolder,filenames,numDays},stocks);
			stocks=new ArrayList<Stock>();
			getStocks();
			SVMchosen=SVMpredict.choose_stocks_to_buy();
			
			//choose intersection of stocks from GP and SVM
			chooseIntersection(buyFile,Integer.parseInt(numDays));
		}
	}
	
	public static void chooseIntersection(String buyFile,int days)
	{

		PrintWriter writer;
		//double gain=0;
		ArrayList<String> intersection=new ArrayList<String>();
		try
		{
			writer=new PrintWriter(buyFile);
			
			if(days>90)
			{
				//going according to GP result
				for(String str:GPchosen)
				{
					writer.println(str);
					intersection.add(str);
				
				}
			}
			else
			{
				//taking intersection of GP result and
				for(String str:GPchosen)
				{
					if(SVMchosen.contains(str))
					{
						writer.println(str);
						intersection.add(str);
					}
				}

			}
			writer.close();

			/*
			for(int i=0;i<stocks.size();i++)
			{
				
				if(intersection.contains(stocks.get(i).getName()))
				{
					gain+=preds.get(i)-stocks.get(i).getPrices().get(stocks.get(i).getPrices().size()-days-1);
				}
			}
			System.out.println("gain!!!!!"+gain);*/
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	//build array of stocks
	public static void getStocks()
	{
		BufferedReader br = null;
		BufferedReader brr = null;
		String str2=null;
		try
		{
			brr=new BufferedReader(new FileReader(filenames));

			ArrayList<Double> prices;
			String str;
			
			// as long as the file has more lines to read
			while ((str = brr.readLine()) != null)
			{
				br=new BufferedReader(new FileReader(datafolder+"/"+str));
				prices=new ArrayList<Double>();
				String name="";
				
				//reading the history of each stock
				while((str2=br.readLine()) != null)
				{
					String [] splitted=str2.split(",");
					name=splitted[0];
					prices.add(Double.parseDouble(splitted[5]));
				}
				
				stocks.add(new Stock(name,prices));
				br.close();
			}
			
			brr.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	//run the GP and save best formula in file
	public static void trainGP()
	{
		int days=Integer.parseInt(numDays);
	
		try 
		{
			//cutting the history to 500 days
			for(Stock s:stocks){
				
				List<Double> sub=s.getPrices().subList(s.getPrices().size()-500,s.getPrices().size());
				ArrayList<Double> lst=new ArrayList<Double>();
				for(Double n:sub)
					lst.add(n);
				s.setPrices(lst);

			}
			//running random algorithm for monkey problem
			StockProblem.run_alg(stocks,days,modelFile);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	//find stocks to buy according to GP formula
	public static void predictGP()
	{
		
		try
		{
			FileInputStream fw;
			int days=Integer.parseInt(numDays);
			fw = new FileInputStream(modelFile);

			//reading the object using the object output stream
			ObjectInputStream os=new ObjectInputStream(fw);
			IGPProgramHolder holder=(IGPProgramHolder) os.readObject();
			os.close();
			IGPProgram gp=holder.getGPProgram();

			//get variables from object
			Variable vx1=holder.getVx1();
			Variable vx2=holder.getVx2();
			Variable vx3=holder.getVx3();
			Variable vx4=holder.getVx4();
			
			Variable vx5=holder.getVx5();
			Variable vx6=holder.getVx6();
			Variable vx7=holder.getVx7();
			Variable vx8=holder.getVx8();
			Variable vx9=holder.getVx9();
			Variable vx10=holder.getVx10();
			Variable vx11=holder.getVx11();
			Variable vx12=holder.getVx12();
			Variable vx13=holder.getVx13();
			Variable vx14=holder.getVx14();
			Variable vx15=holder.getVx15();
			Variable vx16=holder.getVx16();
			Variable vx17=holder.getVx17();
			Variable vx18=holder.getVx18();
			Variable vx19=holder.getVx19();
			Variable vx20=holder.getVx20();
			Variable vx21=holder.getVx21();
			Variable vx22=holder.getVx22();
			Variable vx23=holder.getVx23();
			Variable vx24=holder.getVx24();
			Variable vx25=holder.getVx25();
			Variable vx26=holder.getVx26();
			Variable vx27=holder.getVx27();
			Variable vx28=holder.getVx28();
			Variable vx29=holder.getVx29();
			Variable vx30=holder.getVx30();
			Variable vx31=holder.getVx31();
			Variable vx32=holder.getVx32();
			Variable vx33=holder.getVx33();
			Variable vx34=holder.getVx34();
			Variable vx35=holder.getVx35();
			Variable vx36=holder.getVx36();
			Variable vx37=holder.getVx37();
			Variable vx38=holder.getVx38();
			Variable vx39=holder.getVx39();
			Variable vx40=holder.getVx40();
			Variable vx41=holder.getVx41();
			Variable vx42=holder.getVx42();
			Variable vx43=holder.getVx43();
			Variable vx44=holder.getVx44();
			Variable vx45=holder.getVx45();
			Variable vx46=holder.getVx46();
			Variable vx47=holder.getVx47();
			Variable vx48=holder.getVx48();
			Variable vx49=holder.getVx49();
			Variable vx50=holder.getVx50();
			Variable vx51=holder.getVx51();
			Variable vx52=holder.getVx52();
			Variable vx53=holder.getVx53();
			Variable vx54=holder.getVx54();
			Variable vx55=holder.getVx55();
			Variable vx56=holder.getVx56();
			Variable vx57=holder.getVx57();
			Variable vx58=holder.getVx58();
			Variable vx59=holder.getVx59();
			Variable vx60=holder.getVx60();
			Variable vx61=holder.getVx61();
			Variable vx62=holder.getVx62();
			Variable vx63=holder.getVx63();
			Variable vx64=holder.getVx64();
			Variable vx65=holder.getVx65();
			Variable vx66=holder.getVx66();
			Variable vx67=holder.getVx67();
			Variable vx68=holder.getVx68();
			Variable vx69=holder.getVx69();
			Variable vx70=holder.getVx70();
			Variable vx71=holder.getVx71();
			Variable vx72=holder.getVx72();
			Variable vx73=holder.getVx73();
			Variable vx74=holder.getVx74();
			Variable vx75=holder.getVx75();
			Variable vx76=holder.getVx76();
			Variable vx77=holder.getVx77();
			Variable vx78=holder.getVx78();
			Variable vx79=holder.getVx79();
			Variable vx80=holder.getVx80();
			Variable vx81=holder.getVx81();
			Variable vx82=holder.getVx82();
			Variable vx83=holder.getVx83();
			Variable vx84=holder.getVx84();
			Variable vx85=holder.getVx85();
			Variable vx86=holder.getVx86();
			Variable vx87=holder.getVx87();
			Variable vx88=holder.getVx88();
			Variable vx89=holder.getVx89();
			Variable vx90=holder.getVx90();
			Variable vx91=holder.getVx91();
			Variable vx92=holder.getVx92();
			Variable vx93=holder.getVx93();
			Variable vx94=holder.getVx94();
			Variable vx95=holder.getVx95();
			Variable vx96=holder.getVx96();
			Variable vx97=holder.getVx97();
			Variable vx98=holder.getVx98();
			Variable vx99=holder.getVx99();
			Variable vx100=holder.getVx100();
			Variable vx101=holder.getVx101();
			Variable vx102=holder.getVx102();
			Variable vx103=holder.getVx103();
			Variable vx104=holder.getVx104();
			Variable vx105=holder.getVx105();
			Variable vx106=holder.getVx106();
			Variable vx107=holder.getVx107();
			Variable vx108=holder.getVx108();
			Variable vx109=holder.getVx109();
			Variable vx110=holder.getVx110();
			Variable vx111=holder.getVx111();
			Variable vx112=holder.getVx112();
			Variable vx113=holder.getVx113();
			Variable vx114=holder.getVx114();
			Variable vx115=holder.getVx115();
			Variable vx116=holder.getVx116();
			Variable vx117=holder.getVx117();
			Variable vx118=holder.getVx118();
			Variable vx119=holder.getVx119();
			Variable vx120=holder.getVx120();
			Variable vx121=holder.getVx121();
			Variable vx122=holder.getVx122();
			Variable vx123=holder.getVx123();
			Variable vx124=holder.getVx124();
			Variable vx125=holder.getVx125();
			Variable vx126=holder.getVx126();
			Variable vx127=holder.getVx127();
			Variable vx128=holder.getVx128();
			Variable vx129=holder.getVx129();
			Variable vx130=holder.getVx130();
			Variable vx131=holder.getVx131();
			Variable vx132=holder.getVx132();
			Variable vx133=holder.getVx133();
			Variable vx134=holder.getVx134();
			Variable vx135=holder.getVx135();
			Variable vx136=holder.getVx136();
			Variable vx137=holder.getVx137();
			Variable vx138=holder.getVx138();
			Variable vx139=holder.getVx139();
			Variable vx140=holder.getVx140();
			Variable vx141=holder.getVx141();
			Variable vx142=holder.getVx142();
			Variable vx143=holder.getVx143();
			Variable vx144=holder.getVx144();
			Variable vx145=holder.getVx145();
			Variable vx146=holder.getVx146();
			Variable vx147=holder.getVx147();
			Variable vx148=holder.getVx148();
			Variable vx149=holder.getVx149();
			Variable vx150=holder.getVx150();
			Variable vx151=holder.getVx151();
			Variable vx152=holder.getVx152();
			Variable vx153=holder.getVx153();
			Variable vx154=holder.getVx154();
			Variable vx155=holder.getVx155();
			Variable vx156=holder.getVx156();
			Variable vx157=holder.getVx157();
			Variable vx158=holder.getVx158();
			Variable vx159=holder.getVx159();
			Variable vx160=holder.getVx160();
			Variable vx161=holder.getVx161();
			Variable vx162=holder.getVx162();
			Variable vx163=holder.getVx163();
			Variable vx164=holder.getVx164();
			Variable vx165=holder.getVx165();
			Variable vx166=holder.getVx166();
			Variable vx167=holder.getVx167();
			Variable vx168=holder.getVx168();
			Variable vx169=holder.getVx169();
			Variable vx170=holder.getVx170();
			Variable vx171=holder.getVx171();
			Variable vx172=holder.getVx172();
			Variable vx173=holder.getVx173();
			Variable vx174=holder.getVx174();
			Variable vx175=holder.getVx175();
			Variable vx176=holder.getVx176();
			Variable vx177=holder.getVx177();
			Variable vx178=holder.getVx178();
			Variable vx179=holder.getVx179();
			Variable vx180=holder.getVx180();
			Variable vx181=holder.getVx181();
			Variable vx182=holder.getVx182();
			Variable vx183=holder.getVx183();
			Variable vx184=holder.getVx184();
			Variable vx185=holder.getVx185();
			Variable vx186=holder.getVx186();
			Variable vx187=holder.getVx187();
			Variable vx188=holder.getVx188();
			Variable vx189=holder.getVx189();
			Variable vx190=holder.getVx190();
			Variable vx191=holder.getVx191();
			Variable vx192=holder.getVx192();
			Variable vx193=holder.getVx193();
			Variable vx194=holder.getVx194();
			Variable vx195=holder.getVx195();
			Variable vx196=holder.getVx196();
			Variable vx197=holder.getVx197();
			Variable vx198=holder.getVx198();
			Variable vx199=holder.getVx199();
			Variable vx200=holder.getVx200();
			Variable vx201=holder.getVx201();
			Variable vx202=holder.getVx202();
			Variable vx203=holder.getVx203();
			Variable vx204=holder.getVx204();


			//cutting history of each stock to 200 days
			for(Stock s:stocks){
		
				//Double pred=s.getPrices().get(s.getPrices().size()-1);
				List<Double> sub=s.getPrices().subList(s.getPrices().size()-200,s.getPrices().size());

				ArrayList<Double> lst=new ArrayList<Double>();
				for(Double n:sub)
					lst.add(n);
				
				s.setPrices(lst);

				//preds.add(pred);
			}


			os.close();

			//predictions according to formula
			ArrayList<Double> predictions=new ArrayList<Double>();
			Object[] noargs = new Object[0];

			for(Stock s:stocks){

				double[] minmax=StockProblem.getMinAndMax(s.getPrices(), 0);
				
				//min price in 200 days
				vx1.set(minmax[0]);
				//max price in 200 days
				vx2.set(minmax[1]);
				//avg of last 'days' days
				vx3.set(StockProblem.avg(0, days, s.getPrices()));
				//moving average
				vx4.set(StockProblem.movAvg(0, days, s.getPrices()));
				
				//closing prices of 200 days
				vx5.set(s.getPrices().get(0));
				vx6.set(s.getPrices().get(1));
				vx7.set(s.getPrices().get(2));
				vx8.set(s.getPrices().get(3));
				vx9.set(s.getPrices().get(4));
				vx10.set(s.getPrices().get(5));
				vx11.set(s.getPrices().get(6));
				vx12.set(s.getPrices().get(7));
				vx13.set(s.getPrices().get(8));
				vx14.set(s.getPrices().get(9));
				vx15.set(s.getPrices().get(10));
				vx16.set(s.getPrices().get(11));
				vx17.set(s.getPrices().get(12));
				vx18.set(s.getPrices().get(13));
				vx19.set(s.getPrices().get(14));
				vx20.set(s.getPrices().get(15));
				vx21.set(s.getPrices().get(16));
				vx22.set(s.getPrices().get(17));
				vx23.set(s.getPrices().get(18));
				vx24.set(s.getPrices().get(19));
				vx25.set(s.getPrices().get(20));
				vx26.set(s.getPrices().get(21));
				vx27.set(s.getPrices().get(22));
				vx28.set(s.getPrices().get(23));
				vx29.set(s.getPrices().get(24));
				vx30.set(s.getPrices().get(25));
				vx31.set(s.getPrices().get(26));
				vx32.set(s.getPrices().get(27));
				vx33.set(s.getPrices().get(28));
				vx34.set(s.getPrices().get(29));
				vx35.set(s.getPrices().get(30));
				vx36.set(s.getPrices().get(31));
				vx37.set(s.getPrices().get(32));
				vx38.set(s.getPrices().get(33));
				vx39.set(s.getPrices().get(34));
				vx40.set(s.getPrices().get(35));
				vx41.set(s.getPrices().get(36));
				vx42.set(s.getPrices().get(37));
				vx43.set(s.getPrices().get(38));
				vx44.set(s.getPrices().get(39));
				vx45.set(s.getPrices().get(40));
				vx46.set(s.getPrices().get(41));
				vx47.set(s.getPrices().get(42));
				vx48.set(s.getPrices().get(43));
				vx49.set(s.getPrices().get(44));
				vx50.set(s.getPrices().get(45));
				vx51.set(s.getPrices().get(46));
				vx52.set(s.getPrices().get(47));
				vx53.set(s.getPrices().get(48));
				vx54.set(s.getPrices().get(49));
				vx55.set(s.getPrices().get(50));
				vx56.set(s.getPrices().get(51));
				vx57.set(s.getPrices().get(52));
				vx58.set(s.getPrices().get(53));
				vx59.set(s.getPrices().get(54));
				vx60.set(s.getPrices().get(55));
				vx61.set(s.getPrices().get(56));
				vx62.set(s.getPrices().get(57));
				vx63.set(s.getPrices().get(58));
				vx64.set(s.getPrices().get(59));
				vx65.set(s.getPrices().get(60));
				vx66.set(s.getPrices().get(61));
				vx67.set(s.getPrices().get(62));
				vx68.set(s.getPrices().get(63));
				vx69.set(s.getPrices().get(64));
				vx70.set(s.getPrices().get(65));
				vx71.set(s.getPrices().get(66));
				vx72.set(s.getPrices().get(67));
				vx73.set(s.getPrices().get(68));
				vx74.set(s.getPrices().get(69));
				vx75.set(s.getPrices().get(70));
				vx76.set(s.getPrices().get(71));
				vx77.set(s.getPrices().get(72));
				vx78.set(s.getPrices().get(73));
				vx79.set(s.getPrices().get(74));
				vx80.set(s.getPrices().get(75));
				vx81.set(s.getPrices().get(76));
				vx82.set(s.getPrices().get(77));
				vx83.set(s.getPrices().get(78));
				vx84.set(s.getPrices().get(79));
				vx85.set(s.getPrices().get(80));
				vx86.set(s.getPrices().get(81));
				vx87.set(s.getPrices().get(82));
				vx88.set(s.getPrices().get(83));
				vx89.set(s.getPrices().get(84));
				vx90.set(s.getPrices().get(85));
				vx91.set(s.getPrices().get(86));
				vx92.set(s.getPrices().get(87));
				vx93.set(s.getPrices().get(88));
				vx94.set(s.getPrices().get(89));
				vx95.set(s.getPrices().get(90));
				vx96.set(s.getPrices().get(91));
				vx97.set(s.getPrices().get(92));
				vx98.set(s.getPrices().get(93));
				vx99.set(s.getPrices().get(94));
				vx100.set(s.getPrices().get(95));
				vx101.set(s.getPrices().get(96));
				vx102.set(s.getPrices().get(97));
				vx103.set(s.getPrices().get(98));
				vx104.set(s.getPrices().get(99));
				vx105.set(s.getPrices().get(100));
				vx106.set(s.getPrices().get(101));
				vx107.set(s.getPrices().get(102));
				vx108.set(s.getPrices().get(103));
				vx109.set(s.getPrices().get(104));
				vx110.set(s.getPrices().get(105));
				vx111.set(s.getPrices().get(106));
				vx112.set(s.getPrices().get(107));
				vx113.set(s.getPrices().get(108));
				vx114.set(s.getPrices().get(109));
				vx115.set(s.getPrices().get(110));
				vx116.set(s.getPrices().get(111));
				vx117.set(s.getPrices().get(112));
				vx118.set(s.getPrices().get(113));
				vx119.set(s.getPrices().get(114));
				vx120.set(s.getPrices().get(115));
				vx121.set(s.getPrices().get(116));
				vx122.set(s.getPrices().get(117));
				vx123.set(s.getPrices().get(118));
				vx124.set(s.getPrices().get(119));
				vx125.set(s.getPrices().get(120));
				vx126.set(s.getPrices().get(121));
				vx127.set(s.getPrices().get(122));
				vx128.set(s.getPrices().get(123));
				vx129.set(s.getPrices().get(124));
				vx130.set(s.getPrices().get(125));
				vx131.set(s.getPrices().get(126));
				vx132.set(s.getPrices().get(127));
				vx133.set(s.getPrices().get(128));
				vx134.set(s.getPrices().get(129));
				vx135.set(s.getPrices().get(130));
				vx136.set(s.getPrices().get(131));
				vx137.set(s.getPrices().get(132));
				vx138.set(s.getPrices().get(133));
				vx139.set(s.getPrices().get(134));
				vx140.set(s.getPrices().get(135));
				vx141.set(s.getPrices().get(136));
				vx142.set(s.getPrices().get(137));
				vx143.set(s.getPrices().get(138));
				vx144.set(s.getPrices().get(139));
				vx145.set(s.getPrices().get(140));
				vx146.set(s.getPrices().get(141));
				vx147.set(s.getPrices().get(142));
				vx148.set(s.getPrices().get(143));
				vx149.set(s.getPrices().get(144));
				vx150.set(s.getPrices().get(145));
				vx151.set(s.getPrices().get(146));
				vx152.set(s.getPrices().get(147));
				vx153.set(s.getPrices().get(148));
				vx154.set(s.getPrices().get(149));
				vx155.set(s.getPrices().get(150));
				vx156.set(s.getPrices().get(151));
				vx157.set(s.getPrices().get(152));
				vx158.set(s.getPrices().get(153));
				vx159.set(s.getPrices().get(154));
				vx160.set(s.getPrices().get(155));
				vx161.set(s.getPrices().get(156));
				vx162.set(s.getPrices().get(157));
				vx163.set(s.getPrices().get(158));
				vx164.set(s.getPrices().get(159));
				vx165.set(s.getPrices().get(160));
				vx166.set(s.getPrices().get(161));
				vx167.set(s.getPrices().get(162));
				vx168.set(s.getPrices().get(163));
				vx169.set(s.getPrices().get(164));
				vx170.set(s.getPrices().get(165));
				vx171.set(s.getPrices().get(166));
				vx172.set(s.getPrices().get(167));
				vx173.set(s.getPrices().get(168));
				vx174.set(s.getPrices().get(169));
				vx175.set(s.getPrices().get(170));
				vx176.set(s.getPrices().get(171));
				vx177.set(s.getPrices().get(172));
				vx178.set(s.getPrices().get(173));
				vx179.set(s.getPrices().get(174));
				vx180.set(s.getPrices().get(175));
				vx181.set(s.getPrices().get(176));
				vx182.set(s.getPrices().get(177));
				vx183.set(s.getPrices().get(178));
				vx184.set(s.getPrices().get(179));
				vx185.set(s.getPrices().get(180));
				vx186.set(s.getPrices().get(181));
				vx187.set(s.getPrices().get(182));
				vx188.set(s.getPrices().get(183));
				vx189.set(s.getPrices().get(184));
				vx190.set(s.getPrices().get(185));
				vx191.set(s.getPrices().get(186));
				vx192.set(s.getPrices().get(187));
				vx193.set(s.getPrices().get(188));
				vx194.set(s.getPrices().get(189));
				vx195.set(s.getPrices().get(190));
				vx196.set(s.getPrices().get(191));
				vx197.set(s.getPrices().get(192));
				vx198.set(s.getPrices().get(193));
				vx199.set(s.getPrices().get(194));
				vx200.set(s.getPrices().get(195));
				vx201.set(s.getPrices().get(196));
				vx202.set(s.getPrices().get(197));
				vx203.set(s.getPrices().get(198));
				vx204.set(s.getPrices().get(199));

				//executing the formula on the variables
				predictions.add(gp.execute_double(0, noargs));
			}


			//double all=0;
			
			//calculating average of predictions
			double THRESH=calcAvg(predictions);

			if(days>90)
			{
				for(int i=0;i<stocks.size();i++){
					
					//choosing stocks according to treshold
					if(predictions.get(i)>THRESH-45){
						
						GPchosen.add(stocks.get(i).getName());
					}
					//all+=preds.get(i)-stocks.get(i).getPrices().get(199);

				}
			}
			else
			{
				for(int i=0;i<stocks.size();i++){
					
					//choosing stocks higher than threshold and whose predicted price has grown
					if(predictions.get(i)>THRESH  && predictions.get(i)>stocks.get(i).getPrices().get(199)+5){

						GPchosen.add(stocks.get(i).getName());

					}
					//all+=preds.get(i)-stocks.get(i).getPrices().get(199);
				}
		
			}
			
		}
	    catch(Exception e)
	    {
	    	e.printStackTrace();
	    }

}
	
	//calculate average of predictions
	private static double calcAvg(ArrayList<Double> predictions){

		double sum=0;
		// for every Double in the population
		for(Double val:predictions)
		{
			// add this Double fitness
			sum+=val;
		}

		// return the average fitness
		return ((double)sum)/predictions.size();
	}
}
